package top.zhangjianyong.tools.service.api.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import top.zhangjianyong.tools.entity.stock.StockGoods;
import top.zhangjianyong.tools.entity.stock.StockUser;
import top.zhangjianyong.tools.entity.stock.StockUserGoods;
import top.zhangjianyong.tools.mapper.StockGoodsMapper;
import top.zhangjianyong.tools.model.stock.StockGoodsVO;
import top.zhangjianyong.tools.model.stock.StockUserGoodsVO;
import top.zhangjianyong.tools.parm.stock.*;
import top.zhangjianyong.tools.service.api.StockGoodsService;
import top.zhangjianyong.tools.service.api.StockUserGoodsService;
import top.zhangjianyong.tools.service.api.StockUserService;
import top.zhangjianyong.tools.utils.ApiResponse;
import top.zhangjianyong.tools.utils.LockUtil;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author zhangjianyong
 * @since 2025/3/25 下午3:36
 */
@Service
public class StockGoodsServiceImpl extends ServiceImpl<StockGoodsMapper, StockGoods> implements StockGoodsService {

    private final StockUserGoodsService stockUserGoodsService;
    private final StockUserService stockUserService;

    public StockGoodsServiceImpl(@Lazy StockUserGoodsService stockUserGoodsService,
                                 @Lazy StockUserService stockUserService) {
        this.stockUserGoodsService = stockUserGoodsService;
        this.stockUserService = stockUserService;
    }

    @Override
    public ApiResponse save(StockGoodsSaveParam param) {
        StockGoods one = lambdaQuery().eq(StockGoods::getName, param.getName())
                .one();
        if (null != one) return ApiResponse.fail("存在同名物品添加失败");
        StockGoods stockGoods = new StockGoods();
        BeanUtils.copyProperties(param, stockGoods);
        stockGoods.setDelFlag(0);
        return save(stockGoods) ? ApiResponse.success() : ApiResponse.fail("保存失败");
    }

    @Override
    public ApiResponse update(StockGoodsUpdateParam param) {

        StockGoods sameName = lambdaQuery()
                .eq(StockGoods::getName, param.getName())
                .one();
        if (sameName != null && !Objects.equals(sameName.getId(), param.getId()))
            throw new RuntimeException("存在同名物品修改失败");

        return LockUtil.excecute(LockUtil.LockKey.STOCK_GOODS.getLockKey(param.getId()), () -> {
            StockGoods stockGoods = new StockGoods();
            BeanUtils.copyProperties(param, stockGoods);
            //查询已用的数量
            Integer used = stockUserGoodsService.countUsedByGoodsId(stockGoods.getId());
            if (used > stockGoods.getTotal()) return ApiResponse.fail("库存不能小于已借出数量");
            return lambdaUpdate()
                    .eq(StockGoods::getId, stockGoods.getId())
                    .update(stockGoods) ? ApiResponse.success() : ApiResponse.fail("更新失败");
        });
    }

    @Override
    public ApiResponse del(StockGoodsDelParam param) {
        return lambdaUpdate()
                .eq(StockGoods::getId, param.getId())
                .set(StockGoods::getDelFlag, param.getDelFlag())
                .update() ? ApiResponse.success() : ApiResponse.fail("更新失败");
    }

    @Override
    public ApiResponse list(StockGoodsListParam param) {
        List<StockGoodsVO> list = lambdaQuery()
                .like(StrUtil.isNotBlank(param.getKeyword()), StockGoods::getName, param.getKeyword())
                .list().stream().map(stockGoods -> {
                    StockGoodsVO stockGoodsVO = new StockGoodsVO();
                    BeanUtils.copyProperties(stockGoods, stockGoodsVO);
                    return stockGoodsVO;
                }).collect(Collectors.toList());
        for (StockGoodsVO stockGoods : list) {
            Integer used = stockUserGoodsService.countUsedByGoodsId(stockGoods.getId());
            stockGoods.setUsed(used);
        }
        return ApiResponse.success(list);
    }

    @Override
    public ApiResponse userList(StockUserGoodsUserListParam param) {
        List<StockUserGoodsVO> list = stockUserGoodsService.lambdaQuery()
                .eq(StockUserGoods::getStockGoods, param.getGoodsId())
                .orderByAsc(StockUserGoods::getUpdateTime)
                .list().stream().map(stockUserGoods -> {
                    StockUserGoodsVO stockUserGoodsVO = new StockUserGoodsVO();
                    BeanUtils.copyProperties(stockUserGoods, stockUserGoodsVO);
                    return stockUserGoodsVO;
                }).collect(Collectors.toList());
        for (StockUserGoodsVO stockUserGoods : list) {
            StockUser user = stockUserService.getById(stockUserGoods.getStockUser());
            stockUserGoods.setUser(user);
        }
        return ApiResponse.success(list);
    }
}
